package br.com.mauricioreis;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Button;
import android.widget.SimpleAdapter;
import android.widget.TimePicker;
import android.widget.Toast;
import br.com.mauricioreis.db.Perfil;
import br.com.mauricioreis.db.Prato;
import br.com.mauricioreis.db.Refeicao;
import br.com.mauricioreis.db.Util;

public class RefeicaoIncluirAct extends ListActivity {
    private List<Prato> pratos = new ArrayList<Prato>();
    private Refeicao refeicao = null;
    private Button buttonIncluirPrato;
    private Button buttonCancelar;
    private Button buttonSalvar;
    private Button buttonModificarHora;
    private Button buttonConsultarConsumo;
    private Prato itemSelecionado;
    /**
     * identifica se esta é uma alteração (true) ou uma inclusao de refeição (false)
     */
    private boolean isAlteracao;
    private static final ArrayList<HashMap<String, String>> listaPratos = new ArrayList<HashMap<String, String>>();
    private static final int INCLUIR_ID = Menu.FIRST;
    private static final int EXCLUIR_ID = Menu.FIRST + 1;
    public static final int DATE_DIALOG_ID = Menu.FIRST + 2;
    public static final int CONSULTAR_CONSUMO_ID = Menu.FIRST + 3;

    private int hora;
    private int minuto;
    private int segundo;
    // the callback received when the user "sets" the date in the dialog
    private final TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {

        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            RefeicaoIncluirAct.this.hora = hourOfDay;
            RefeicaoIncluirAct.this.minuto = minute;
            RefeicaoIncluirAct.this.segundo = 0;
            updateButtonModificarHora();
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.refeicao_incluir);
        // identifica se é alteração o inclusão de refeicao
        Bundle extras = getIntent().getExtras();
        int idRefeicao = extras.getInt("idRefeicao");
        // se foi passada refeicao, então é a tela de alteração
        if (idRefeicao != 0) {
            carregaRefeicao(idRefeicao);
            isAlteracao = true;

        } else {
            // cria uma nova refeição no banco apenas para obter se id
            insereRefeicao();
            isAlteracao = false;
        }
        montaViewRefeicaoIncluir();
        montaBotaoIncluirPrato();
        montaBotaoCancelar();
        montaBotaoSalvar();
        montaBotaoModificarHora();
        montaBotaoConsultarConsumo();
        registerForContextMenu(this.getListView());
        montaViewRefeicaoIncluir();
    }

    private void carregaRefeicao(int idRefeicao) {
        this.refeicao = new Refeicao();
        this.refeicao.setId(idRefeicao);
        this.refeicao = Refeicao.consultar(this, this.refeicao);
    }

    private void montaBotaoConsultarConsumo() {
        buttonConsultarConsumo = (Button) findViewById(R.id.refeicaoIncluirConsumo);
        buttonConsultarConsumo.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                Bundle extras = getIntent().getExtras();
                Intent i = new Intent(RefeicaoIncluirAct.this, ConsumoAct.class);
                i.putExtra("dia", extras.getInt("dia"));
                i.putExtra("mes", extras.getInt("mes"));
                i.putExtra("ano", extras.getInt("ano"));
                i.putExtra("idRefeicao", RefeicaoIncluirAct.this.refeicao.getId());
                startActivityForResult(i, CONSULTAR_CONSUMO_ID);
            }
        });
    }

    private void montaBotaoModificarHora() {
        buttonModificarHora = (Button) findViewById(R.id.refeicaoIncluirModificarHora);

        // faz o clique do botão mostrar uma caixa de dialogo
        buttonModificarHora.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog(DATE_DIALOG_ID);
            }
        });
        // se for alteração de refeição, pega os dados de hora da refeicao
        if (isAlteracao) {
            hora = this.refeicao.getData().get(Calendar.HOUR_OF_DAY);
            minuto = this.refeicao.getData().get(Calendar.MINUTE);
            segundo = this.refeicao.getData().get(Calendar.SECOND);
            // senao pega a data atual para inicializar o botão de data
        } else {
            final Calendar c = Calendar.getInstance();
            hora = c.get(Calendar.HOUR_OF_DAY);
            minuto = c.get(Calendar.MINUTE);
            segundo = c.get(Calendar.SECOND);
        }
        // display the current date (this method is below)
        updateButtonModificarHora();

    }

    /**
     * Atualiza a hora do botão que modifica e mostra a hora
     */
    private void updateButtonModificarHora() {
        buttonModificarHora.setText(Util.formataExibicaoHoraMinuto(hora, minuto));
    }

    /**
     * Chamado sempre que uma caixa de dialogo é criada
     */
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case DATE_DIALOG_ID:
            return new TimePickerDialog(this, mTimeSetListener, hora, minuto, true);
        }
        return null;
    }

    private void montaBotaoIncluirPrato() {
        buttonIncluirPrato = (Button) findViewById(R.id.refeicaoIncluirPrato);
        buttonIncluirPrato.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent i = new Intent(RefeicaoIncluirAct.this, PratoAct.class);
                i.putExtra("idRefeicao", refeicao.getId());
                startActivityForResult(i, INCLUIR_ID);

            }
        });
    }

    private void montaBotaoSalvar() {
        buttonSalvar = (Button) findViewById(R.id.refeicaoIncluirSalvar);
        buttonSalvar.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // verifica se existe ao menos um prato na refeição
                if (pratos != null && pratos.size() != 0) {
                    // se existe, atualiza dados da refeição e fecha a tela
                    RefeicaoIncluirAct.this.atualizaDataRefeicao();
                    finish();
                } else {
                    Toast.makeText(RefeicaoIncluirAct.this, "Você deve incluir ao menos um prato", Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

    /**
     * Retorna a data da refeição com base nos dados da tela no formato calendar
     */
    private Calendar obtemDataAtualizadaRefeicao() {
        Bundle extras = getIntent().getExtras();
        // obtem o id da medida
        int dia = extras.getInt("dia");
        int mes = extras.getInt("mes");
        int ano = extras.getInt("ano");
        return Util.montaCalendarComDataHora(dia, mes, ano, hora, minuto, segundo);
    }

    /**
     * Atualiza os dados referentes a data de inclusão da refeição
     */
    protected void atualizaDataRefeicao() {
        // Obtem todos os dados da refeição que esta sendo modificada nesta tela
        Refeicao refeicaoAtualizada = Refeicao.consultar(this, this.refeicao);
        // Seta a hora
        refeicaoAtualizada.setData(obtemDataAtualizadaRefeicao());
        // atualiza
        Refeicao.editar(this, refeicaoAtualizada);
    }

    private void montaBotaoCancelar() {
        buttonCancelar = (Button) findViewById(R.id.refeicaoIncluirCancelar);
        if (isAlteracao) {
            buttonCancelar.setText("Voltar");
        }
        buttonCancelar.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                trataFechamentoDaJanela();
            }
        });
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        // Pega posição do item selecionado
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
        int posicaoItem = info.position;
        // pega o objeto medida da posição selecionada
        HashMap<String, String> linhaSelecionada = (HashMap<String, String>) this.getListView().getItemAtPosition(posicaoItem);
        itemSelecionado = new Prato();
        itemSelecionado.setId(Integer.valueOf(linhaSelecionada.get("idPrato")));
        itemSelecionado = Prato.consultar(this, itemSelecionado);
        menu.add(0, EXCLUIR_ID, 0, "Excluir");
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case EXCLUIR_ID:
            if (itemSelecionado != null) {
                Prato.excluir(RefeicaoIncluirAct.this, itemSelecionado);
                montaViewRefeicaoIncluir();
                itemSelecionado = null;
                return true;
            }
        }
        return super.onContextItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        montaViewRefeicaoIncluir();
    }

    @Override
    public void onBackPressed() {
        trataFechamentoDaJanela();
    }

    /**
     * Pergunta ao usuario se ele deseja sair sem salvar refeição em caso positivo, exclui refeição e pratos já inseridos
     * 
     * @return
     */
    private void trataFechamentoDaJanela() {
        // se fol alteração, simplismente fecha a janela
        if (isAlteracao) {
            finish();
            // se não cria um prompt para confirmar decisão do usuario e deletar refeição
        } else {
            criaAlertBoxFechamentoDeJanela();
        }
    }

    private void criaAlertBoxFechamentoDeJanela() {
        AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
        alertbox.setMessage("Deseja realmente cancelar a inclusão desta refeicao?");
        final Refeicao refeicaoParaExcluir = this.refeicao;
        alertbox.setPositiveButton("Sim", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                // se for inclusão, deleta a refeição, se for alteração, apenas não altera a refeição
                if (!isAlteracao) {
                    RefeicaoIncluirAct.excluiRefeicao(RefeicaoIncluirAct.this, refeicaoParaExcluir);
                }
                finish();
            }
        });
        alertbox.setNegativeButton("Não", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface arg0, int arg1) {
                // Se usuario clicar no não, apenas permanece na mesma tela
            }
        });
        // display box
        alertbox.show();

    }

    protected static void excluiRefeicao(Activity atividade, Refeicao refeicaoParaExcluir) {
        Prato.excluir(atividade, refeicaoParaExcluir);
        Refeicao.excluir(atividade, refeicaoParaExcluir);
    }

    /**
     * Insere refeição com o perfil atual
     */
    private void insereRefeicao() {
        this.refeicao = new Refeicao();
        this.refeicao.setData(obtemDataAtualizadaRefeicao());
        this.refeicao.setIdPerfil(Perfil.obtemUltimoPerfil(this).getId());
        this.refeicao.setId(Refeicao.incluir(this, this.refeicao).intValue());

    }

    private void montaViewRefeicaoIncluir() {
        listaPratos.clear();
        SimpleAdapter adapter = new SimpleAdapter(this, listaPratos, R.layout.refeicao_incluir_linhas, new String[] { "alimento",
                "quantidadeMedida" }, new int[] { R.id.prato_alimento, R.id.prato_medida });
        // obtem lista de pratos da refeição
        Prato prato = new Prato();
        prato.setIdRefeicao(this.refeicao.getId());
        pratos = Prato.listar(this, prato);
        // popula listagem da tela
        for (Prato p : pratos) {
            String nomeAlimento = null;
            String quantidadeMedida = p.getQuantidade().toString();
            if (p.getMedidaAlimento(this) != null && p.getMedidaAlimento(this).getAlimento(this) != null) {
                nomeAlimento = p.getMedidaAlimento(this).getAlimento(this).getNome();
            }
            if (p.getMedidaAlimento(this) != null && p.getMedidaAlimento(this).getMedida(this) != null) {
                quantidadeMedida += " - " + p.getMedidaAlimento(this).getMedida(this).getNome();
            }
            HashMap<String, String> temp = new HashMap<String, String>();
            temp.put("alimento", nomeAlimento);
            temp.put("quantidadeMedida", quantidadeMedida);
            temp.put("idPrato", Integer.toString(p.getId()));
            listaPratos.add(temp);
        }
        setListAdapter(adapter);
    }
}